package com.dingreading.cloud.admin.service.impl;

import com.dingreading.cloud.admin.dto.StoreDto;
import com.dingreading.cloud.admin.dto.StoreForTrainLogDto;
import com.dingreading.cloud.admin.entity.Stores;
import com.dingreading.cloud.admin.entity.table.StoresTableDef;
import com.dingreading.cloud.admin.mapper.StoresMapper;
import com.dingreading.cloud.admin.service.StoresService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.DateUtil;
import com.dingreading.cloud.common.util.EnumOperationType;
import com.dingreading.cloud.common.util.PageDto;
import com.dingreading.cloud.common.util.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class StoresServiceImpl extends BaseServiceImpl<StoresMapper, Stores, StoresTableDef> implements StoresService {


    @Override
    protected StoresTableDef getTable() {
        return StoresTableDef.stores;
    }

    @Override
    public PageDto<StoreDto> pageList(
            PageUtil pageUtil, String corpUid, String keyword, Integer operateStatus, Integer enabled, Integer roleType,
            String headStaffUid, Integer activated, Integer contractStatus, Integer protectStatus
    ) {
        //设置其他参数
        Map<String, Object> otherParams = new HashMap<>();
        otherParams.put("corpUid", corpUid);
        otherParams.put("keyword", keyword);
        otherParams.put("operateStatus", operateStatus);
        otherParams.put("enabled", enabled);
        otherParams.put("roleType", roleType);
        otherParams.put("headStaffUid", headStaffUid);
        otherParams.put("activated", activated);
        otherParams.put("contractStatus", contractStatus);
        otherParams.put("protectStatus", protectStatus);

        int selfType = EnumOperationType.SELF.getType();
        int consortiumType = EnumOperationType.CONSORTIUM.getType();
        int brandJoinType = EnumOperationType.BRAND_JOIN.getType();
        int productJoinType = EnumOperationType.PRODUCT_JOIN.getType();
        int easyProductJoinType = EnumOperationType.EASY_PRODUCT_JOIN.getType();
        int cooperationType = EnumOperationType.COOPERATION.getType();
        otherParams.put("selfType", selfType);
        otherParams.put("consortiumType", consortiumType);
        otherParams.put("brandJoinType", brandJoinType);
        otherParams.put("productJoinType", productJoinType);
        otherParams.put("easyProductJoinType", easyProductJoinType);
        otherParams.put("cooperationType", cooperationType);

        Page<StoreDto> page = getMapper().xmlPaginate("pageListXml", Page.of(pageUtil.getPage(), pageUtil.getRows()), otherParams);

        long totalRow = page.getTotalRow();
        List<StoreDto> list = page.getRecords();

        // 结果
        PageDto<StoreDto> dto = new PageDto<>();
        dto.setList(list);
        dto.setTotal(totalRow);

        return dto;
    }

    @Override
    public Stores getByUid(String uid) {
        return getMapper().selectOneByCondition(table.uid.eq(uid));
    }

    @Override
    public List<Stores> getByUids(List<String> uids) {
        return getMapper().selectListByCondition(table.uid.in(uids));
    }

    @Override
    public List<Stores> getByCorpUid(String corpUid, Integer enabled) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.corpUid.eq(corpUid));
        if (enabled != null)
            condition.and(table.enabled.eq(enabled));
        return getMapper().selectListByCondition(condition);
    }

    @Override
    public List<Stores> getStoreMarker() {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.lng.ne(""))
                .and(table.lat.ne(""))
                .and(table.enabled.eq(1));

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.corpUid, table.uid, table.storeName, table.lng, table.lat)
                .from(table)
                .where(condition);

        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public List<Stores> getByKeywordAndEnable(String keyword, Integer enabled) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (StringUtils.isNotBlank(keyword))
            condition.and(table.storeName.like(keyword)
                    .or(table.address.like(keyword)));
        if (null != enabled)
            condition.and(table.enabled.eq(enabled));

        QueryWrapper wrapper = QueryWrapper.create()
                .where(condition)
                .orderBy(table.id.desc());

        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public boolean updateOperateInfo(String storeUid, String operateStaffUid, String operateStaffName, String operateStaffPhone) {
        QueryCondition condition = QueryCondition.createEmpty();
        condition.and(table.uid.eq(storeUid));

        return UpdateChain.of(Stores.class)
                .set(table.operateStaffUid, operateStaffUid)
                .set(table.operateStaffName, operateStaffName)
                .set(table.operateStaffPhone, operateStaffPhone)
                .where(condition)
                .update();
    }

    @Override
    public boolean updateActivated(String storeUid, Integer activated) {
        UpdateChain<Stores> update = UpdateChain.of(Stores.class);
        if (activated.equals(1))
            update.set(table.activatedTime, DateUtil.getNowDatetime());
        else
            update.set(table.activatedTime, null);
        return update.set(table.activated, activated)
                .where(table.uid.eq(storeUid))
                .update();
    }

    @Override
    public boolean updateEnabled(String storeUid, Integer enabled) {
        return UpdateChain.of(Stores.class)
                .set(table.enabled, enabled)
                .where(table.uid.eq(storeUid))
                .update();
    }

    @Override
    public boolean updateLngAndLat(String storeUid, String lng, String lat, Integer protectType, Integer protectRadius) {
        return UpdateChain.of(Stores.class)
                .set(table.lat, lat)
                .set(table.lng, lng)
                .set(table.protectType, protectType)
                .set(table.protectRadius, protectRadius)
                .where(table.uid.eq(storeUid))
                .update();
    }

    @Override
    public List<Stores> getNearCycleStoreList(String longitudeMin, String longitudeMax, String latitudeMin, String latitudeMax) {
        QueryCondition condition = table.lat.between(latitudeMin, latitudeMax)
                .and(table.lng.between(longitudeMin, longitudeMax))
                .and(table.protectType.eq(1));
        return getMapper().selectListByCondition(condition);
    }

    @Override
    public List<String> corpUidBySelfAndConsortium() {
        QueryCondition condition = table.operationType.in(EnumOperationType.SELF.getType(), EnumOperationType.CONSORTIUM.getType())
                .and(table.enabled.eq(1));
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.corpUid)
                .from(table)
                .where(condition);
        return getMapper().selectObjectListByQueryAs(wrapper, String.class);
    }

    @Override
    public List<Stores> selfAndConsortiumList() {
        QueryCondition condition = table.operationType.in(EnumOperationType.SELF.getType(), EnumOperationType.CONSORTIUM.getType())
                .and(table.enabled.eq(1));
        return getMapper().selectListByCondition(condition);
    }

    @Override
    public List<Stores> joinList() {
        QueryCondition condition = table.operationType.notIn(EnumOperationType.SELF.getType(), EnumOperationType.CONSORTIUM.getType())
                .and(table.enabled.eq(1));
        return getMapper().selectListByCondition(condition);
    }

    @Override
    public List<Stores> getProtectStoreList() {
        QueryCondition condition = table.protectType.isNotNull();
        QueryWrapper wrapper = QueryWrapper.create()
                .select(
                        table.uid, table.storeName, table.enabled,
                        table.lng, table.lat, table.protectType, table.protectRadius
                )
                .from(table)
                .where(condition);

        return getMapper().selectListByQuery(wrapper);
    }

    @Override
    public Stores getByCorpUidAndStoreUid(String corpUid, String storeUid) {
        QueryCondition condition = QueryCondition.createEmpty()
                .and(table.corpUid.eq(corpUid))
                .and(table.uid.eq(storeUid));
        return getMapper().selectOneByCondition(condition);
    }

    @Override
    public R<Object> searchStore(String headStaffUid, String headStaffName, String keyword) {
        if (StringUtils.isBlank(headStaffUid))
            return R.fail("请选择总部员工");
        if (StringUtils.isBlank(keyword))
            return R.fail("未输入搜索内容");
        QueryCondition condition = QueryCondition.createEmpty()
                .and(table.storeName.like(keyword).or(table.address.like(keyword)).or(table.phone.like(keyword)
                        .or(table.province.like(keyword)).or(table.city.like(keyword)).or(table.county.like(keyword))
                        .or(table.operateStaffName.like(keyword)).or(table.contractCode.like(keyword)))
                );
        List<Stores> stores = getMapper().selectListByCondition(condition);
        return R.ok(stores);
    }

    @Override
    public StoreDto getDtoByUid(String storeUid) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.uid.eq(storeUid));
        return getMapper().selectOneByQueryAs(wrapper, StoreDto.class);
    }

    @Override
    public List<StoreForTrainLogDto> getStores(List<String> storeUids) {
        QueryCondition condition = QueryCondition.createEmpty()
                .and(table.uid.in(storeUids));
        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.uid, table.storeName)
                .where(condition);
        return getMapper().selectListByQueryAs(wrapper, StoreForTrainLogDto.class);
    }

}
